package extraction;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;


import tools.FrenchTokenizer;
import tools.Normalizer;

public class Extraction {

	public static String STOP_WORDS = "data/mot_moins_frequents.txt";

	/**
	 * dictionnaire de mots
	 */
	public static ArrayList<String> mots = new ArrayList<String>();
	
	/**
	 * 20 mots significatifs pour chaque polarité
	 * 	rempli dans classifieur correspondant
	 */
	public HashMap<String, ArrayList<String>> mots_significatifs;


	public static ArrayList<String> getMots() {
		return mots;
	}

	private static HashMap<String, Categorie> initialiseMapStats(){
		HashMap<String, Categorie> statsParClasses = new HashMap<String, Categorie>();

		// Création des types de statistiques
		for (String type : Categorie.getTypePolarite()){
			if (!type.contains("test_"))
				statsParClasses.put(type, new Categorie(type));
		}
		return statsParClasses;
	}

	/**
	 * Méthode qui permet d'analyser un fichier passé en parametre.
	 * On va y appeler le méthode d'extraction des lignes du fichier, puis traiter
	 * chacunes de ces lignes avec la méthode analyseLigne.
	 * @param nomFic : Fichier à traiter.
	 * @return 
	 * @throws IOException 
	 */
	public HashMap<String, Categorie> analyseFichier (String nomFic) throws IOException {

		ArrayList<String> lignesFichier;
		// On extrait les lignes du fichier
		lignesFichier = extractionLignesFichier(nomFic);

		HashMap<String, Categorie> statsParClasses;

		if (lignesFichier.size() > 0) {
			// Si ce n'est pas un fichier de test
			if(lignesFichier.get(0).split("\",\"").length == 5) {
				// On crée une map qui contiendra les statistiques par classes
				statsParClasses = initialiseMapStats();

				// Pour chacunes des lignes du fichier, nous allons extraire les mots
				// et les elements du message.
				for (String ligne : lignesFichier) {
					analyseLigne (ligne, statsParClasses);
				}

			}
			else {			// Sinon si nous avons un fichier de test
				statsParClasses = new HashMap<String, Categorie>();
				statsParClasses.put("test_polarite", new Categorie("test_polarite"));
				
				// Pour chacunes des lignes du fichier Test, nous allons extraire les mots
				// et les elements du message.
				for (String ligne : lignesFichier) {
					analyseLigneTest (ligne, statsParClasses);
				}
			}
			
			return statsParClasses;
		}
		else {
			return null;
		}


		
	}	


	private static void analyseLigneTest(String ligne, HashMap<String, Categorie> statsParClasses) throws IOException {
		// On découpe les différents champs de la ligne
		String [] tabChamps = ligne.split("\",\"");
		int indiceText = tabChamps.length-1;
		String polarite = "test_polarite";

		tabChamps[0] = tabChamps[0].substring(1); //on enleve le " du début
		tabChamps[indiceText] = tabChamps[indiceText].substring(0, tabChamps[indiceText].length()-1); //on enleve le " de la fin


		// On retire le # ou les @ qui pourraient etre présent
		tabChamps[indiceText] = tabChamps[indiceText].replace("#", "");
		tabChamps[indiceText] = tabChamps[indiceText].replace("@", "");

		// Nous faisons appel au Normalizer du premier projet d'EIT pour recupèrer les mots.
		Normalizer norm = new FrenchTokenizer(STOP_WORDS);
		ArrayList<String> result = norm.normalizeLigne(tabChamps[indiceText], true);


		// On extrait les différents champs d'un tweet, puis on l'insère.
		Tweet m = new Tweet(tabChamps[0], polarite, tabChamps[1], tabChamps[2], tabChamps[indiceText]);
		m.setLongueurMessage(result.size());
		m.setMotsText(result);
		statsParClasses.get(polarite).addTweet(m);

//		//on remplit la liste de mots au total
//		for (String mot : result){
//			if (!mots.contains(mot))
//				mots.add(mot);
//		}


		// Insertion des mots dans la map "mots", en fonction de la polarité
		statsParClasses.get(polarite).addListeMotsOcc(result); //occurence
		// Insertion des mots dans la map "motsTweet", en fonction de la polarité
		statsParClasses.get(polarite).addListeMotsTweet(result); //nb de tweet qui comprennent le mot




	}

	/**
	 * Cette méthode permet d'extraire toutes les lignes d'un fichiers dans un ArrayList
	 * qui est renvoyé.
	 * @param nomFic : Nom du fichier à extraire.
	 * @return un ArrayList contenant 
	 * @throws IOException 
	 */
	public static ArrayList<String> extractionLignesFichier (String nomFic) throws IOException {

		InputStream ips=new FileInputStream(nomFic); 
		InputStreamReader ipsr;

		// Verification du type du fichier
		if ( nomFic.endsWith(".txt")) 
			ipsr=new InputStreamReader(ips);
		else {			
			System.err.println("Mauvais type de fichier.");
			return null;
		}

		BufferedReader br=new BufferedReader(ipsr);
		String line;
		ArrayList<String> lignesFichier = new ArrayList<String>();
		// Pour chaque lignes du fichier
		while ((line=br.readLine())!=null){
			// On vérifie si nous avons bien 4 ou 5 champs sur cette ligne
			if ( 5 >= line.split("\",\"").length){
				lignesFichier.add(line);		// Et nous l'insérons dans l'ArrayList
			}
		}
		br.close(); 
		return lignesFichier;
	}

	/**
	 * Méthode qui analyse une ligne passée en parametre afin d'en extraire
	 * les différentes parties d'un message, ainsi que les mots du tweetText.
	 * @param ligne : la ligne à analyser.
	 * @param test 
	 * @throws IOException 
	 */
	private void analyseLigne (String ligne, HashMap<String, Categorie> statsParClasses) throws IOException {
		// On découpe les différents champs de la ligne
		String [] tabChamps = ligne.split("\",\"");

		tabChamps[0] = tabChamps[0].substring(1); //on enleve le " du début
		tabChamps[4] = tabChamps[4].substring(0, tabChamps[4].length()-1); //on enleve le " de la fin

		boolean polariteOk = false;

		// On vérifie que la polarité existe dans notre liste
		for (String mot : Categorie.getTypePolarite()){
			if (tabChamps[1].equals(mot)){
				polariteOk = true;
			}
		}

		if (polariteOk){


			// On retire le # ou les @ qui pourraient etre présent
			tabChamps[4] = tabChamps[4].replace("#", "");
			tabChamps[4] = tabChamps[4].replace("@", "");

			// Nous faisons appel au Normalizer du premier projet d'EIT pour recupèrer les mots.
			Normalizer norm = new FrenchTokenizer(STOP_WORDS);
			ArrayList<String> result = norm.normalizeLigne(tabChamps[4], true);


			//on enleve mots significatifs
			if (mots_significatifs != null){
				String polarite = tabChamps[1];
				ArrayList<String> test_mots = new ArrayList<String>();
				if (polarite.equals("positive")){
					test_mots = mots_significatifs.get("positive");				
				}
				else if (polarite.equals("negative")){
					test_mots = mots_significatifs.get("negative");
				}
				else if (polarite.equals("neutral")){
					test_mots = mots_significatifs.get("neutral");
				}
				else if (polarite.equals("irrelevant")){
					test_mots = mots_significatifs.get("irrelevant");
				}

				//si le tweet contient des mots significatifs, on les enleve
				for (String mot : test_mots){
					if  (result.contains(mot))
						result.remove(mot);
				}
			}
			
			// On extrait les différents champs d'un tweet, puis on l'insère.
			Tweet m = new Tweet(tabChamps[0], tabChamps[1], tabChamps[2], tabChamps[3], tabChamps[4]);
			m.setLongueurMessage(result.size());
			m.setMotsText(result);
			statsParClasses.get(tabChamps[1]).addTweet(m);

			//on remplit la liste de mots au total
			for (String mot : result){
				if (!mots.contains(mot))
					mots.add(mot);
			}


			// Insertion des mots dans la map "mots", en fonction de la polarité
			statsParClasses.get(tabChamps[1]).addListeMotsOcc(result); //occurence
			// Insertion des mots dans la map "motsTweet", en fonction de la polarité
			statsParClasses.get(tabChamps[1]).addListeMotsTweet(result); //nb de tweet qui comprennent le mot


		}
		else {
			System.err.println("Polarité non existante.");
			return;
		}
	}



	public static void main(String[] args) {
		Extraction e = new Extraction();
		try {
			e.analyseFichier("data/trainMelange.txt");

		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}


}
